package com.summer.safe.config.filter;

import com.summer.safe.config.exception.IncorrectCaptchaException;
import com.summer.safe.utils.Global;
import com.summer.safe.utils.HttpKit;
import com.summer.safe.utils.StringUtils;
import com.summer.safe.utils.UserUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

/**
 * 因为登录成功后不跳转到，设定后的url，许重新FormAuthenticationFilter
 *
 */
public class ShiroFormAuthcFilter extends FormAuthenticationFilter {
    protected Logger logger = LoggerFactory.getLogger(getClass());


    public ShiroFormAuthcFilter() {
        super();
    }

    /**
     * 创建Token
     * @param request
     * @param response
     * @return
     */
    @Override
    protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
        String username = getUsername(request);
        String password = getPassword(request);
        if (password==null){
            password = "";
        }
        boolean rememberMe = isRememberMe(request);
        String host = StringUtils.getRemoteAddr((HttpServletRequest)request);
        return new UsernamePasswordToken(username, password.toCharArray(), rememberMe, host);
    }




    /**
     * 重定向
     * @param request
     * @param response
     * @throws Exception
     */
    @Override
    protected void issueSuccessRedirect(ServletRequest request,
                                        ServletResponse response) throws Exception {
        WebUtils.issueRedirect(request, response, getSuccessUrl(), null, true);
    }


    /**
     * 登录成功调用的方法
     * @param token
     * @param subject
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @Override
    protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception {

        return super.onLoginSuccess(token, subject, request, response);

    }

    /**
     *
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {

        if (isLoginRequest(request, response)) {
            if (isLoginSubmission(request, response)) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Login submission detected.  Attempting to execute login.");
                }
                try{
                    captchaValidate((HttpServletRequest) request);
                    return executeLogin(request, response);
                }catch (AuthenticationException  e){
                    UsernamePasswordToken token = (UsernamePasswordToken) createToken(request, response);
                    return onLoginFailure(token, e, request, response);
                }

            } else {
                if (logger.isTraceEnabled()) {
                    logger.trace("Login page view.");
                }
                return true;
            }
        }
        else {
            this.saveRequestAndRedirectToLogin(request, response);
            return false;
        }
    }

    // 验证码校验
    protected void captchaValidate(HttpServletRequest request) {
        //缓存中的验证码
        Session session = UserUtils.getSession();
        String code = (String) session.getAttribute(Global.KAPTCHA_SESSION_KEY);
        //用户输入的验证码
        String kaptcha = HttpKit.getRequest().getParameter(Global.CAPTCHA_CODE).trim();
        if (StringUtils.isEmpty(kaptcha) || !kaptcha.equalsIgnoreCase(code)) {
            throw new IncorrectCaptchaException();

        }

    }
    /**
     * 登录失败调用事件
     */
    @Override
    protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {
        String className = e.getClass().getName(),
                message = "未知错误";
         if (UnknownAccountException.class.getName().equals(className)) {
            message = "用户名错误";
        } else if (IncorrectCredentialsException.class.getName().equals(className)) {
            message = "密码不正确";
        } else if (LockedAccountException.class.getName().equals(className)) {
            message = "账户已锁定";
        } else  if (ExcessiveAttemptsException.class.getName().equals(className)) {
            message = "用户名或密码错误次数过多";
        } else  if (AuthenticationException.class.getName().equals(className)) {
             message = "认证失败！";
        } else  if (IncorrectCaptchaException.class.getName().equals(className)) {
             message = "验证码错误！";
         }
        request.setAttribute(getFailureKeyAttribute(), className);
        request.setAttribute(Global.DEFAULT_MESSAGE_PARAM, message);
        return true;
    }




}